package com.googlecode.sere.translation

import scala.collection.mutable.{Map => MutableMap}
import com.googlecode.sere.util.Logging
import com.googlecode.sere.core._

object SerializerRegistry extends Logging {

	private val registry = MutableMap.empty[ResourceType, MutableMap[MediaType, Serializer]]

  def register(serializer: Serializer, resourceType: ResourceType = NullResourceType) {
    registry.getOrElseUpdate(resourceType, MutableMap.empty)(serializer.mediaType) = serializer
  }

  /**
   * With the resource type and the accepted types, does server side content
   * negotiation, and returns the best matched media type and its Serializer.
   * In case no type matches, returns the list of the ones that would
   */
  def get(resourceType: ResourceType, types: AcceptedTypes):
    (Option[(MediaType, Serializer)], Set[MediaType]) = {

    logger.debug("Searching for serializer of {} as {} in {}",
      Array(resourceType.getClass.getName, types, registry))

    val specificSerializers = registry.getOrElse(resourceType, MutableMap.empty)
    val genericSerializers = registry.getOrElse(NullResourceType, MutableMap.empty)

    val serializers = specificSerializers ++ genericSerializers
    val best = types.bestMatch(serializers.keySet.toSet)

    best match {
      case Some(mediaType) => (Some((mediaType, serializers(mediaType))), Set())
      case None => (None, serializers.keySet.toSet)
    }
  }
}